#include "F2-Sd-W.h"

#include <stdio.h>
#include <stdio.h>
#include <iostream>
#include <fstream>
#include <time.h>
#include <stdlib.h>
#include <time.h>

#ifndef WIN32
#include "../Model/cmodel.h"
#include "../Model/cmachine.h"
#include "../Model/cbuffer.h"
#include "../Model/cpart.h"
#include "../Model/lib.h"
#else
#include "..\\cmodel.h"
#include "..\\cmachine.h"
#include "..\\cbuffer.h"
#include "..\\cpart.h"
#include "..\\lib.h"

#endif



extern int O_1[C_out+1][M+1];	//工艺矩阵，类别i在机器j上的工序编号

extern int p_[NR+1];				//工序i的加工时间，

extern int s_[NR+1][NR+1];		//工序i到j的切换时间

extern int 	R_0_c[n_0+1];	//需求序列类别号码
extern double 	R_0_d[n_0+1];	//需求序列交货期
extern double  R_0_dw[n_0+1][2]; //需求的交货窗口

extern bool HasToQuit;

using namespace std;


#include "../GA/GA.h"


#define Exp_Time 10

int main(int argc, char **argv)
{
	//1-Set Basic Data
	time_t t;
	time(&t);
	srand(t);
	//printf("hello world\n");
	cout<<"Begin"<<endl;
	F2_Sd_W_Set_Data();

	cout<<"data prepared"<<endl;

	Population p[Exp_Time];
	for(int i=0;i<Exp_Time;i++){
		cout<<".";
		//p[i].GA();
		p[i].NicheGA();
	}
	cout<<endl;
	for(int i=0;i<Exp_Time;i++){
		p[i].ShowBest();
	}

   //穷举试验
	//enumeration();
	if(HasToQuit){cout<<"A error detect."<<endl;}
	return 0;
}

void F2_Sd_W_Set_Data()
{
		///////// 工艺矩阵 //////////
	// O_1[i][j] 最终产品类型为i的工件在机器j上的工序编号
	for(int i=0;i<=C_out;i++)
	{
		for(int j=0;j<=M;j++)
		{
			O_1[i][j]=-1;//非法值
		}
	}
	O_1[1][1]=1;		O_1[1][2]=5;
	O_1[2][1]=2;		O_1[2][2]=6;
	O_1[3][1]=3;		O_1[3][2]=7;
	O_1[4][1]=4;		O_1[4][2]=8;
	/////////////////////////////
	///////// 加工时间 //////////
	//p_[k]=工序k的加工时间
	//
	p_[0]=-1;//invalid
	///////////////////
	p_[1]=1;
	p_[2]=2;
	p_[3]=1;
	p_[4]=2;
	p_[5]=2;
	p_[6]=1;
	p_[7]=2;
	p_[8]=2;
	/////////////////////////////
	
	////////// 切换矩阵 ///////////
	//s_[i][j]，从工序i切换到j的时间
	//
	for(int i=0;i<=NR;i++)
	{
		for(int j=0;j<=NR;j++)
		{
			s_[i][j]=-1;//invalid
		}
	}
	////////////////////
	
	s_[1][1]=0;	s_[1][2]=1;	s_[1][3]=1;	s_[1][4]=1;
	s_[2][1]=1;	s_[2][2]=0;	s_[2][3]=1;	s_[2][4]=1;
	s_[3][1]=1;	s_[3][2]=1;	s_[3][3]=0;	s_[3][4]=1;
	s_[4][1]=1;	s_[4][2]=1;	s_[4][3]=1;	s_[4][4]=0;
	
													s_[5][5]=0;	s_[5][6]=1;	s_[5][7]=1;	s_[5][8]=1;
													s_[6][5]=1;	s_[6][6]=0;	s_[6][7]=1;	s_[6][8]=1;
													s_[7][5]=1;	s_[7][6]=1;	s_[7][7]=0;	s_[7][8]=1;
													s_[8][5]=1;	s_[8][6]=1;	s_[8][7]=1;	s_[8][8]=0;
	
	
	 /////////////////////////////
	/////////// 原始需求 ///////////
	//R_0_c[k]----原始需求第k个产品最终类别;
	//R_0_d[k]----交货期，本模型中无效
	//
	R_0_c[0]=-1;
	R_0_d[0]=-1.0;
	///////////////
	R_0_c[1]=1;		R_0_d[1]=5;
	R_0_c[2]=1;		R_0_d[2]=7;
	R_0_c[3]=2;		R_0_d[3]=6;
	R_0_c[4]=2;		R_0_d[4]=7;
	R_0_c[5]=3;		R_0_d[5]=7;	
	R_0_c[6]=3;		R_0_d[6]=10;
	R_0_c[7]=3;		R_0_d[7]=12;
	R_0_c[8]=4;		R_0_d[8]=7;
	R_0_c[9]=4;		R_0_d[9]=8;
	R_0_c[10]=4;	R_0_d[10]=13;	
	
	
	//50个A-15 B-15 C-10 D-10
	for(int i=1;i<=CHROMOSOME_LENGTH;i++)
	{
		R_0_c[i]=4;
		if(i<=15){
			R_0_c[i]=1;
		}
		else if(i<=30)
		{
			R_0_c[i]=2;
		}
		else if(i<=40)
		{
			R_0_c[i]=3;
		}
		else if(i<=50)
		{
			R_0_c[i]=4;
		}
		else{
			cout<<"WRONG..."<<endl;
			return;
		}
		R_0_d[i]=10;
        //cout<<i<<"Setdate ok."<<R_0_c[i]<<endl;
	}
	
	cout<<"R_0_c[]=";
	for(int j=1;j<=CHROMOSOME_LENGTH;j++)
	{
		cout<<" "<<R_0_c[j];
	}
	cout<<" "<<endl;
	
	///////
	//交货窗口
	for(int k=0;k<n_0+1;k++)
	{
		//R_0_dw[k][0]----交货窗口下界;
		//R_0_dw[k][1]----交货窗口上界;
		R_0_dw[k][0]=5;
		R_0_dw[k][1]=8;
	}
}


double F2_Sd_W_Trail(int data[])
{
	CModel theShop;
	CBuffer theSource;
	CMachine M1;
	CBuffer B1;
	CMachine M2;
	CBuffer  theShip;
	theSource.setCapacity(100);
	B1.setCapacity(100);
	theShip.setCapacity(100);
	theShop.AddElement(&theSource);
	theShop.AddElement(&theShip);
	theShop.AddElement(&M1);
	theShop.AddElement(&B1);
	theShop.AddElement(&M2);
	
	M1.AddPreviousElement(&theSource);
	M1.AddNextElement(&B1);
	M1.setMachineID(1);

	M2.AddPreviousElement(&B1);
	M2.AddNextElement(&theShip);
	M2.setMachineID(2);

	CPart part[n_0];
	
	for (int i=0;i<n_0;i++) {
		//part[i].setDueTime(R_0_d[i+1]]);
		part[i].setFinalType(data[i]);
		//
		theSource.GetAPartIn(&part[i]);
	}
	
	theShop.Run();
	return theShip.showW_sigma(R_0_dw[1][0],R_0_dw[1][1],0.4,0.6,false);
}

